package com.sam.designpatterns

import java.util.*

// 员工基类
abstract class Staff(var name: String) {
    var kpi: Int
    init {
        kpi = Random().nextInt(10)
    }
    // 接受 Visitor 的访问
    abstract fun accept(visitor: Visitor)
}


class Engineer(name: String) : Staff(name) {
    override fun accept(visitor: Visitor) {
        visitor.visit(this)
    }
    // 代码行数，随机10万内模拟
    fun getCodeLine(): Int {
        return Random().nextInt(100_000)
    }
}
class Manager(name: String) : Staff(name) {
    // 一年做的产品数量,随机10以内模拟
    var products: Int = Random().nextInt(10)
    override fun accept(visitor: Visitor) {
        visitor.visit(this)
    }
}


interface Visitor {
    // 访问工程师类型
    fun visit(engineer: Engineer)

    // 访问经理类型
    fun visit(manager: Manager)
}

// 前面说过了，CEO 关注的是:
// 工程师的 KPI 和经理的 KPI 以及经理的新产品的数量
class CEO : Visitor {
    override fun visit(engineer: Engineer) {
        println("工程师：${engineer.name}, KPI: ${engineer.kpi}")
    }

    override fun visit(manager: Manager) {
        println("经理：${manager.name}, KPI: ${manager.kpi}, 新产品数：${manager.products}")
    }
}

// CTO 关注：而 CTO 只关注工程师的代码量、新产品数量
class CTO : Visitor {
    override fun visit(engineer: Engineer) {
        println("工程师：${engineer.name}, 代码量: ${engineer.getCodeLine()} 行")
    }

    override fun visit(manager: Manager) {
        println("经理：${manager.name}, 新产品数：${manager.products}")
    }
}

// 员工业务报表
class BusinessReport {
    val staffs: MutableList<Staff> = mutableListOf(
            Engineer("Erich Gamma"),
            Engineer("Richard Helm"),
            Engineer("Ralph Johnson"),
            Engineer("John Vlissides"),
            Manager("GoF")
    )
    fun showReport(visitor: Visitor) {
        for (staff in staffs) {
            staff.accept(visitor)
        }
    }
}

fun main() {
    val businessReport = BusinessReport()
    println("=========== CEO看报表 ===========")
    val ceo = CEO()
    businessReport.showReport(ceo)
    println("=========== CTO看报表 ===========")
    val cto = CTO()
    businessReport.showReport(cto)
}
